Skip to content

gh-117404: Add structured version info for compression modules - #150567

Open
serhiy-storchaka wants to merge 10 commits into
python:mainfrom
serhiy-storchaka:compression-library-versions-2
Open

gh-117404: Add structured version info for compression modules#150567
serhiy-storchaka wants to merge 10 commits into
python:mainfrom
serhiy-storchaka:compression-library-versions-2

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented May 29, 2026

Copy link
Copy Markdown
Member

Add a number of constants in modules zlib, bz2, lzma, and compression.zstd, which provide information about the version of libraries that were used for building the module and that are actually loaded:

  • zlib.zlib_version -- an alias of zlib.ZLIB_RUNTIME_VERSION
  • zlib.ZLIB_VERSION_INFO
  • zlib.zlib_version_info
  • zlib.zlibng_version
  • zlib.ZLIBNG_VERSION_INFO
  • zlib.zlibng_version_info
  • bz2.bzlib_version
  • bz2.bzlib_version_info
  • lzma.LZMA_VERSION
  • lzma.lzma_version
  • lzma.LZMA_VERSION_INFO
  • lzma.lzma_version_info
  • compression.zstd.ZSTD_VERSION
  • compression.zstd.ZSTD_VERSION_INFO

Make compression.zstd.zstd_version_info a named tuple.

@read-the-docs-community

read-the-docs-community Bot commented May 29, 2026

Copy link
Copy Markdown

Add a number of constants in modules zlib, bz2, lzma, and
compression.zstd, which provide information about the version
of libraries that were used for building the module and that
are actually loaded:

* zlib.zlib_version -- an alias of zlib.ZLIB_RUNTIME_VERSION
* zlib.ZLIB_VERSION_INFO
* zlib.zlib_version_info
* zlib.zlibng_version
* zlib.ZLIBNG_VERSION_INFO
* zlib.zlibng_version_info
* bz2.bzlib_version
* bz2.bzlib_version_info
* lzma.LZMA_VERSION
* lzma.lzma_version
* lzma.LZMA_VERSION_INFO
* lzma.lzma_version_info
* compression.zstd.ZSTD_VERSION
* compression.zstd.ZSTD_VERSION_INFO

Make compression.zstd.zstd_version_info a named tuple.
@serhiy-storchaka
serhiy-storchaka force-pushed the compression-library-versions-2 branch from f57fc45 to 76354de Compare May 29, 2026 07:39
Comment thread Doc/library/compression.zstd.rst
@serhiy-storchaka

Copy link
Copy Markdown
Member Author

@emmatyping, could you please look at this PR?

…-versions-2

# Conflicts:
#	Doc/whatsnew/3.16.rst
@serhiy-storchaka

Copy link
Copy Markdown
Member Author

@gpshead, could you please review this PR? It implements the naming scheme we converged on in gh-117404 (*_version for the string version, *_version_info for a named tuple, ALLCAPS for the compile-time version).

@emmatyping

Copy link
Copy Markdown
Member

Sorry for not reviewing sooner, will try to get to this tomorrow

…-versions-2

# Conflicts:
#	Doc/whatsnew/3.16.rst
Comment thread Doc/library/bz2.rst
Comment thread Doc/library/compression.zstd.rst
Comment thread Doc/library/zlib.rst
Comment thread Doc/library/zlib.rst Outdated
The version string of the zlib library actually loaded by the interpreter.

.. versionadded:: 3.3
.. versionchanged:: next

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should soft-deprecate the old one, otherwise we're inconsistent.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe later, when the new name became widespread.

Comment thread Doc/library/zlib.rst Outdated
Comment thread Lib/test/pythoninfo.py
Comment thread Lib/test/test_bz2.py Outdated
self.assertGreaterEqual(v.minor, 0)
self.assertGreaterEqual(v.patch, 0)

self.assertEqual(bz2.bzlib_version.split(',')[0], '%d.%d.%d' % v)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I build with --with-bzip2=bzip2-rs:

test test_bz2 failed -- Traceback (most recent call last):
  File "/home/stan/dev/cpython/Lib/test/test_bz2.py", line 1247, in test_bzlib_version
    self.assertEqual(bz2.bzlib_version.split(',')[0], '%d.%d.%d' % v)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: '1.1.0-libbz2-rs-sys-0.2.5' != '1.1.0'
- 1.1.0-libbz2-rs-sys-0.2.5
+ 1.1.0

Comment thread Lib/test/test_zstd.py Outdated
Comment thread Modules/_bz2module.c Outdated
{0}
};

static PyStructSequence_Desc zlib_version_desc = {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was all copy pasted but not updated for bz2.

Comment thread Modules/zlibmodule.c Outdated
int pos = 0;
unsigned int major = 0, minor = 0, revision = 0, subversion = 0;

sscanf(string, "%u.%u.%u.%u", &major, &minor, &revision, &subversion);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sscanf can fail?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it can. Then we will get zeros for missing components. I think it is better than a hard error.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest a comment, to avoid people agents trying to fix this in the future.

Comment thread Doc/library/bz2.rst
Comment thread Doc/library/compression.zstd.rst
Comment thread Doc/library/compression.zstd.rst Outdated
Comment thread Doc/library/zlib.rst
Comment thread Doc/library/zlib.rst Outdated
The version string of the zlib library actually loaded by the interpreter.

.. versionadded:: 3.3
.. versionchanged:: next

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe later, when the new name became widespread.

Comment thread Modules/_bz2module.c Outdated
Comment thread Modules/_bz2module.c Outdated
Comment thread Modules/zlibmodule.c Outdated
int pos = 0;
unsigned int major = 0, minor = 0, revision = 0, subversion = 0;

sscanf(string, "%u.%u.%u.%u", &major, &minor, &revision, &subversion);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it can. Then we will get zeros for missing components. I think it is better than a hard error.

serhiy-storchaka and others added 2 commits August 22, 2026 15:53
Co-authored-by: Stan Ulbrych <stan@python.org>
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
* Register collect_bz2() and collect_lzma() in pythoninfo's collect_info().
* Do not assume a particular suffix of bz2.bzlib_version: libbz2-rs reports
  "1.1.0-libbz2-rs-sys-0.2.5" where bzip2 reports "1.0.8, 13-Jul-2019".
* Document ZLIB_RUNTIME_VERSION and zlib_version as a single entry and
  tell in which version each of them was added.
* Tell which fields the runtime *_version_info named tuples have by
  referring to their compile-time counterparts.
* Remove a line duplicated when applying a suggestion for ZLIB_VERSION_INFO.
* Fix indentation, alignment and line lengths of the added code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@serhiy-storchaka

Copy link
Copy Markdown
Member Author

Thank you for your review @StanFromIreland. I addressed your comments.

@StanFromIreland StanFromIreland left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few little nits, but otherwise I like the API.

Comment thread Doc/library/bz2.rst Outdated
Miscellaneous
-------------

Information about the version of the bzip2 compression library in use

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe clarify what "in use" means, as in other places we distinguish compile/run time.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It repeats existing phrase from zlib.rst. What is your suggestion?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For zlib, we have both runtime and compile time constants, whereas here we only have runtime. It's not clear in the documentation if bzlib_version is runtime or compile time information. So, I suggest either clarifying here, or below in their documentation (but that's a little duplicative).

Comment thread Modules/_zstd/_zstdmodule.c Outdated
};

static PyStructSequence_Desc zstd_version_desc = {
"_zstd.zstd_version_info", /* name */

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, this will leak into the repr now, right? We could do like we have elsewhere:

cpython/Modules/posixmodule.c

Lines 2504 to 2505 in 999a046

static PyStructSequence_Desc stat_result_desc = {
"os.stat_result", /* name; see issue gh-63408 */

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlike os.stat_result, the name of this type is not public. It cannot be used, because it conflicts with the name of the instance (like in sys.version_info and other precedences).

Interesting, Claude had the same complaint, but I convinced it.

Comment thread Modules/_bz2module.c Outdated
};


PyDoc_STRVAR(bzlib_version__doc__,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PyDoc_STRVAR(bzlib_version__doc__,
PyDoc_STRVAR(bzlib_version_info__doc__,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, this will need a lot of changes.

Comment thread Modules/zlibmodule.c Outdated
};

static PyObject *
make_zlibng_version(PyTypeObject *type, const char *string)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is almost the same as make_zlib_version, it can be refactored.

* Explain in a comment why the result of sscanf() is not checked.
* Merge make_zlib_version() and make_zlibng_version() into a single
  make_version_info().
* Rename the static names for the *_version_info named tuples, so that
  they match the name of the type.
* Tell in the bz2 docs that bzlib_version and bzlib_version_info are the
  version of the library loaded at runtime, and that the version used for
  building the module is not available.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants